package com.example.usb.util;

import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.os.Environment;

import com.example.usb.ai.AiV3Bean;
import com.example.usb.dao.DbConstant;
import com.lib.uvccamera.utils.DebugLog;
import com.lib.uvccamera.utils.FileUtils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import static com.lib.uvccamera.utils.DebugLog.LOGHsc;

public class ImageUtils {


    /**
     * @param bitmap        图片
     * @param left          坐标
     * @param top           坐标
     * @param width         脸宽
     * @param height        脸长
     * @param rotationAngle 旋转角度
     * @return
     */
    public static Bitmap new_rotaingOtherImageView(Bitmap bitmap, int left, int top, int width, int height, int rotationAngle) {
        int x = 0;
        int y = 0;
        int newWidth = 0;
        int newHeight = 0;
        //人脸是正面 ,人脸顺时针偏移了 0-5
        x = getCorrectXPoint((Double.valueOf(left - width)).intValue());
        y = getCorrectYPoint((Double.valueOf(top - height * 0.66d)).intValue());
        newWidth = Double.valueOf(3d * width).intValue();
        newHeight = (int) (newWidth * 3 / 4d);
        DebugLog.d(LOGHsc + " rotationAngle---25°以内-- " + rotationAngle + " x " + x + " y " + y + " newWidth " + newWidth + " newHeight " + newHeight + " bitmap.getWidth() "
                + bitmap.getWidth() + " bitmap.getHeight()  " + bitmap.getHeight());
        if (x + newWidth > bitmap.getWidth()) {
            newWidth = bitmap.getWidth() - x - 1;
        }
        if (y + newHeight > bitmap.getHeight()) {
            newHeight = bitmap.getHeight() - y - 1;
        }
        // 创建新的图片
        return Bitmap.createBitmap(bitmap, x, y, newWidth, newHeight);
    }

    /**
     * Bitmap转换成Base64字符串
     *
     * @param bitmap
     * @return
     */
    public static byte[] bitmap2StrByte(Bitmap bitmap) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        return baos.toByteArray();
    }

    /**
     * @param bitmap        图片
     * @param left          坐标
     * @param top           坐标
     * @param width         脸宽
     * @param height        脸长
     * @param rotationAngle 旋转角度
     * @return
     */
    public static Bitmap rotaingOtherImageView(Bitmap bitmap, int left, int top, int width, int height, int rotationAngle) {
        int x = 0;
        int y = 0;
        int newWidth = 0;
        int newHeight = 0;
        if (rotationAngle == 0 || rotationAngle > 0 && rotationAngle < 5 || rotationAngle > -5 && rotationAngle < 0) {
            //人脸是正面 ,人脸顺时针偏移了 0-5
            x = getCorrectXPoint(left);
            y = getCorrectYPoint((int) (top - 0.5f * height));
            newWidth = width;
            newHeight = getCorrentHeight((int) (3 * height / 2f), bitmap.getHeight());
        } else if (rotationAngle > 5) {
            //人脸顺时针偏移了 5-20
            x = getCorrectXPoint((int) (left - 2 * height * getTanAngle(rotationAngle)));
            y = getCorrectYPoint((int) (top - 0.3f * height));
            newWidth = getCorrentWidth((int) (3 * height * getTanAngle(rotationAngle) + width), bitmap.getWidth());
            newHeight = getCorrentHeight((int) (4 * height / 3f), bitmap.getHeight());
        } else {
            //<0了 [-30,-5]
            if (rotationAngle < -5 && rotationAngle > -20) {
                x = getCorrectXPoint((int) (left - 2 * height * getSinAngle(rotationAngle)));
                y = getCorrectYPoint((int) (top - 0.5f * height));
                newWidth = getCorrentWidth((int) (3 * height * getSinAngle(rotationAngle) + width), bitmap.getWidth());
                newHeight = getCorrentHeight(((int) (3 * height / 2f)), bitmap.getHeight());
            } else {
                x = getCorrectXPoint(left);
                y = getCorrectYPoint((int) (top - 0.5f * height));
                newWidth = getCorrentWidth((int) (height * getSinAngle(rotationAngle) + width * getCosAngle(rotationAngle)), bitmap.getWidth());
                newHeight = getCorrentHeight(((int) (3 * height / 2f)), bitmap.getHeight());

            }
        }

        DebugLog.d(LOGHsc + " rotationAngle---25°以内-- " + rotationAngle + " x " + x + " y " + y + " newWidth " + newWidth + " newHeight " + newHeight + " bitmap.getWidth() "
                + bitmap.getWidth() + " bitmap.getHeight()  " + bitmap.getHeight());
        if (x + newWidth > bitmap.getWidth()) {
            newWidth = bitmap.getWidth() - x - 1;
        }
        if (y + newHeight > bitmap.getHeight()) {
            newHeight = bitmap.getHeight() - y - 1;
        }
        // 创建新的图片
        return Bitmap.createBitmap(bitmap, x, y, newWidth, newHeight);

    }

    /**
     * @param bitmap        图片
     * @param left          坐标
     * @param top           坐标
     * @param width         脸宽
     * @param height        脸长
     * @param rotationAngle 旋转角度
     * @return
     */
    public static Bitmap rotaingImageView(Bitmap bitmap, int left, int top, int width, int height, int rotationAngle) {
        int x = 0;
        int y = 0;
        int newWidth = 0;
        int newHeight = 0;
        if (rotationAngle < 0) {
            if (rotationAngle > -90) {
//                 [-90,-20]
                DebugLog.d(LOGHsc + " rotationAngle在[-90,-20]---- ");
                //人脸逆时针偏移了
                x = getCorrectXPoint((int) (left - 0.5f * height));
                y = getCorrectYPoint((int) (top - width / getSinAngle(rotationAngle) - 0.3f * height / getTanAngle(rotationAngle)));
                newWidth = getCorrentWidth((int) (height / getSinAngle(rotationAngle) + 0.3f * height + width * getCosAngle(rotationAngle)), bitmap.getWidth());
                newHeight = getCorrentHeight((int) (height * getCosAngle(rotationAngle) + width / getSinAngle(rotationAngle) + 0.3f * height / getTanAngle(rotationAngle)), bitmap.getHeight());
            } else {
//                [-180,-90]之间
                DebugLog.d(LOGHsc + " rotationAngle在 [-180,-90]---- ");
                x = getCorrectXPoint((int) (left - getSinAngle(-rotationAngle - 90) * (height * getTanAngle(-rotationAngle - 90) + width)));
                y = getCorrectYPoint((int) (top - height * getSinAngle(-rotationAngle - 90) - width * getCosAngle(-rotationAngle - 90)));
                newWidth = getCorrentWidth((int) (height / getCosAngle(-rotationAngle - 90) + width * getSinAngle(-rotationAngle - 90)), bitmap.getWidth());
                newHeight = getCorrentHeight((int) (3 * height * getSinAngle(-rotationAngle - 90) / 2f + width * getCosAngle(-rotationAngle - 90)), bitmap.getHeight());
            }

        } else {
            //人脸顺时针偏移了
            if (rotationAngle < 90) {
//                    [20,90]
                DebugLog.d(LOGHsc + " rotationAngle在[20,90]---- ");
                x = getCorrectXPoint((int) (left - height * getSinAngle(rotationAngle)));
                y = getCorrectYPoint((int) (top - height / getTanAngle(rotationAngle)));
                newWidth = getCorrentWidth((int) (height * getSinAngle(rotationAngle) + height), bitmap.getWidth());
                newHeight = getCorrentHeight((int) (width / getSinAngle(rotationAngle) + height * getCosAngle(rotationAngle)), bitmap.getHeight());
            } else {
//                90-180之间
                DebugLog.d(LOGHsc + " rotationAngle在[90,180]---- ");
                x = getCorrectXPoint((int) (left - height * getCosAngle(rotationAngle - 90) - width * getSinAngle(rotationAngle - 90)));
                y = getCorrectYPoint((int) (top - height * getSinAngle(rotationAngle - 90)));
                newWidth = getCorrentWidth((int) (3 * height * getCosAngle(rotationAngle - 90) / 2f + width * getSinAngle(rotationAngle - 90)), bitmap.getWidth());
                newHeight = getCorrentHeight((int) (width * getCosAngle(rotationAngle - 90) + 3 * height * getSinAngle(rotationAngle - 90) / 2f), bitmap.getHeight());
            }

        }
        //旋转图片 动作
        Matrix matrix = new Matrix();
        //顺时针旋转
        if (rotationAngle > 0) {
            //(0,90);人脸转正
//            matrix.postRotate(360 - rotationAngle);
            //图片转正
            if (rotationAngle < 90) {
//                [0,90]
                matrix.postRotate(270);
            } else {
//                人脸转正
//                matrix.postRotate(360 - rotationAngle);
                //图片转正(90,180)
                if (rotationAngle < 135) {
//                  90-135°
                    matrix.postRotate(270);
                } else {
                    //135-180°
                    matrix.postRotate(180);
                }
            }

        } else {

            if (rotationAngle > -90) {
                //（-90，0）人脸转正
//                matrix.postRotate(-rotationAngle);
                //图片转正
                matrix.postRotate(90);
            } else {
                if (rotationAngle > -135) {
                    //图片转正（-90，-135）
                    matrix.postRotate(90);
                } else {

                    //图片转正（-135，-180）
                    matrix.postRotate(270);
                }

            }
        }
        DebugLog.d(LOGHsc + " rotationAngle--20°以外---- " + rotationAngle + " x " + x + " y " + y + " newWidth " + newWidth + " newHeight " + newHeight + " bitmap.getWidth() "
                + bitmap.getWidth() + " bitmap.getHeight()  " + bitmap.getHeight());
        if (x + newWidth > bitmap.getWidth()) {
            newWidth = bitmap.getWidth() - x - 1;
        }
        if (y + newHeight > bitmap.getHeight()) {
            newHeight = bitmap.getHeight() - y - 1;
        }
        // 创建新的图片
        return Bitmap.createBitmap(bitmap, x, y, newWidth, newHeight, matrix, true);

    }

    /**
     * @param faceList 数据
     * @param user     图片
     * @return 裁剪的人头
     */
    public static Bitmap getRotateImgae(AiV3Bean.FaceList faceList, Bitmap user) {

        AiV3Bean.FaceList.Location location = faceList.getLocation();
        //旋转角度
        int rotationAngle = (int) location.getRotation();
        int left = (int) location.getLeft();
        int top = (int) location.getTop();
        int right = (int) location.getWidth();
        int bootom = (int) location.getHeight();
        DebugLog.d(LOGHsc + " left " + left + " top " + top + " right " + right + " bootom " + bootom + " rotationAngle " + rotationAngle);
        //TODO:这里如果人头有旋转，则呈现正面
        Bitmap newBitmap = null;
        //如果旋转角度小于40°
        if (Math.abs(rotationAngle) <= 25) {
            newBitmap = rotaingImageView(user, left, top, right, bootom, rotationAngle);
        } else {
            newBitmap = rotaingImageView(user, left, top, right, bootom, rotationAngle);
        }
        return newBitmap;
    }

    /**
     * 返回校验后的人脸高度
     *
     * @param height 高度
     * @param imgH   图片高度
     * @return
     */
    private static int getCorrentHeight(int height, int imgH) {
        if (height > imgH) {
            return imgH - 1;
        }
        return height;
    }

    /**
     * 返回校验后的人脸高度
     *
     * @param width 高度
     * @param imgW  图片高度
     * @return
     */
    private static int getCorrentWidth(int width, int imgW) {
        if (width > imgW) {
            return imgW - 1;
        }
        return width;
    }

    /**
     * 校验脸的Y坐标
     *
     * @param y y坐标
     * @return
     */
    private static int getCorrectYPoint(int y) {
        if (y <= 0) {
            //超出人头范围，返回为0
            return 1;
        }
        return y;
    }

    /**
     * 校验脸的Y坐标
     *
     * @param x x坐标
     * @return
     */
    private static int getCorrectXPoint(int x) {

        if (x <= 0) {
            //超出人头范围，返回为0
            return 1;
        }
        return x;
    }

    /**
     * 获取正玄函数的值
     *
     * @param rotationAngle 角度
     * @return
     */
    private static double getSinAngle(int rotationAngle) {
        return Math.sin(Math.toRadians(Math.abs(rotationAngle)));
    }

    /**
     * 获取正玄函数的值
     *
     * @param rotationAngle 角度
     * @return
     */
    private static double getSinAngle(double rotationAngle) {
        return Math.sin(Math.toRadians(Math.abs(rotationAngle)));
    }

    /**
     * 获取余玄函数的值
     *
     * @param rotationAngle 角度
     * @return
     */
    private static double getCosAngle(int rotationAngle) {
        return Math.cos(Math.toRadians(Math.abs(rotationAngle)));
    }

    /**
     * 获取余玄函数的值
     *
     * @param rotationAngle 角度
     * @return
     */
    private static double getCosAngle(double rotationAngle) {
        return Math.cos(Math.toRadians(Math.abs(rotationAngle)));
    }

    /**
     * 获取正切函数的值
     *
     * @param rotationAngle 角度
     * @return
     */
    private static double getTanAngle(int rotationAngle) {
        return Math.tan(Math.toRadians(Math.abs(rotationAngle)));
    }

    /**
     * 通过人脸得到坐标
     *
     * @param location 属性
     * @return
     */

    //    float[] floats = new float[]{150,200,350,200,350,200,350,600,350,600,150,600,150,600,150,200};
//    float[] floats2 = new float[]{250,300,450,300,450,300,450,600,450,600,250,600,250,600,250,300};
    public static float[] getFacePoint(AiV3Bean.FaceList.Location location) {
        double rotation = location.getRotation();
        float[] floats = new float[16];
        if (rotation > 0) {
            //顺时针 TODO:没有做>90°的设定
            float x1 = (float) location.getLeft();
            float y1 = (float) location.getTop();

            float x2 = (float) (x1 + location.getHeight() * getSinAngle(rotation));
            float y2 = (float) (y1 - location.getHeight() * getCosAngle(rotation));

            float x3 = (float) (x2 + location.getWidth() * getCosAngle(rotation));
            float y3 = (float) (y2 + y2 * getSinAngle(rotation));

            float x4 = (float) (x3 - location.getWidth() * getCosAngle(rotation));
            float y4 = (float) (y3 + location.getWidth() * getSinAngle(rotation));
            floats[0] =x1;
            floats[1] =y1;
            floats[2] =x2;
            floats[3] =y2;
            floats[4] =x2;
            floats[5] =y2;
            floats[6] =x3;
            floats[7] =y3;
            floats[8] =x3;
            floats[9] =y3;
            floats[10] =x4;
            floats[11] =y4;
            floats[12] =x4;
            floats[13] =y4;
            floats[14] =x1;
            floats[15] =y1;
        } else {
            //逆时针
            float x1 = (float) location.getLeft();
            float y1 = (float) location.getTop();
            float x2 = (float) (x1 + location.getWidth() * getCosAngle(rotation));
            float y2 = (float) (y1- location.getWidth() * getSinAngle(rotation));

            float x3 = (float) (x2 + location.getHeight() * getSinAngle(rotation));
            float y3 = (float) (y2 + location.getHeight()  * getCosAngle(rotation));

            float x4 = (float) (x3 - location.getWidth() * getCosAngle(rotation));
            float y4 = (float) (y3 + location.getWidth() * getSinAngle(rotation));
            floats[0] =x1;
            floats[1] =y1;
            floats[2] =x2;
            floats[3] =y2;
            floats[4] =x2;
            floats[5] =y2;
            floats[6] =x3;
            floats[7] =y3;
            floats[8] =x3;
            floats[9] =y3;
            floats[10] =x4;
            floats[11] =y4;
            floats[12] =x4;
            floats[13] =y4;
            floats[14] =x1;
            floats[15] =y1;
        }
        return floats;
    }

    /**
     * 保存图片人脸框的路径
     * @param bmp 图片
     * @return
     */
    public static void saveFaceFrame(Bitmap bmp,String fileName) {
        File file = new File(DbConstant.FRAMEDIR, fileName);
        try {
            FileOutputStream fos = new FileOutputStream(file);
            bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            fos.flush();
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
